package com.stylesmile.demo.aio.demo2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.TimeUnit;

public class AIOServer {
    public static void main(String[] args) {
        try {
            //创建异步通道
            AsynchronousServerSocketChannel serverSocketChannel=AsynchronousServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(8080));
            System.out.println("等待连接中");
            //在AIO中，accept有两个参数，
            // 第一个参数是一个泛型，可以用来控制想传递的对象
            // 第二个参数CompletionHandler，用来处理监听成功和失败的逻辑
            //  如此设置监听的原因是因为这里的监听是一个类似于递归的操作，每次监听成功后要开启下一个监听
            serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
                //请求成功处理逻辑
                @Override
                public void completed(AsynchronousSocketChannel result, Object attachment) {
                    System.out.println("连接成功，处理数据中");
                    //开启新的监听
                    serverSocketChannel.accept(null,this);
                    handledata(result);
                }
                @Override
                public void failed(Throwable exc, Object attachment) {
                    System.out.println("失败");
                }
            });
            try {
                TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void handledata(AsynchronousSocketChannel result) {
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        //通道的read方法也带有三个参数
        //1.目的地：处理客户端传递数据的中转缓存，可以不使用
        //2.处理客户端传递数据的对象
        //3.处理逻辑，也有成功和不成功的两个写法
        result.read(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                if (result>0){
                    attachment.flip();
                    byte[] array = attachment.array();
                    System.out.println(new String(array));
                }
            }
            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("失败");
            }
        });
    }
}
